package com.nuts.base.config;

import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Set;

import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * redis配置
 * 
 * @author 许自辉
 * @date 2017年7月20日 上午9:08:27
 */
@Configuration
@AutoConfigureAfter(RedisConfig.class)
public class RedisConfig {

	// @Value("${spring.redis.cluster.nodes}")
	// private String clusterNodes;

	@SuppressWarnings("rawtypes")
	@Bean
	public RedisSerializer fastJsonRedisSerializer() {
		return new FastJsonRedisSerializer<Object>(Object.class);
	}

	// @Bean
	// public RedisConnectionFactory redisConnectionFactory() {
	// return redisConnectionFactorys();
	// }

//	@Bean
//	public RedisTemplate<String, Object> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory,
//			@SuppressWarnings("rawtypes") RedisSerializer fastJson2JsonRedisSerializer) {
//		RedisTemplate<String, Object> template = new RedisTemplate<>();
//		template.setKeySerializer(new StringRedisSerializer());
////		template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
//		template.setValueSerializer(fastJson2JsonRedisSerializer);
//		template.setConnectionFactory(redisConnectionFactory);
//		return template;
//	}

	@Bean
	public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory,
			@SuppressWarnings("rawtypes") RedisSerializer fastJsonRedisSerializer) {
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		redisTemplate.setConnectionFactory(redisConnectionFactory);
		// 设置value的序列化规则和 key的序列化规则	
		// 设置值（value）的序列化采用FastJsonRedisSerializer。
        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
        // 设置键（key）的序列化采用StringRedisSerializer。
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

		redisTemplate.afterPropertiesSet();
		return redisTemplate;
	}

	/**
	 * 注入封装RedisTemplate @Title: redisUtil @return RedisUtil @autor lpl @date
	 * 2017年12月21日 @throws
	 */
	@Bean(name = "redisUtil")
	public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
		RedisUtil redisUtil = new RedisUtil();
		redisUtil.setRedisTemplate(redisTemplate);
		return redisUtil;
	}

	/**
	 * Redis集群的配置 @return RedisClusterConfiguration @autor lpl @date
	 * 2017年12月22日 @throws
	 */
	// @Bean
	// public RedisClusterConfiguration redisClusterConfiguration(){
	// RedisClusterConfiguration redisClusterConfiguration = new
	// RedisClusterConfiguration();
	// //Set<RedisNode> clusterNodes
	// String[] serverArray = clusterNodes.split(",");
	//
	// Set<RedisNode> nodes = new HashSet<RedisNode>();
	//
	// for(String ipPort:serverArray){
	// String[] ipAndPort = ipPort.split(":");
	// nodes.add(new RedisNode(ipAndPort[0].trim(),Integer.valueOf(ipAndPort[1])));
	// }
	//
	// redisClusterConfiguration.setClusterNodes(nodes);
	// redisClusterConfiguration.setMaxRedirects(mmaxRedirectsac);
	//
	// return redisClusterConfiguration;
	// }

	// @Bean
	// public JedisPoolConfig getRedisConfig() {
	// JedisPoolingClientConfigurationBuilder config = new JedisPoolConfig();
	// config.setMaxIdle(maxIdle);
	// config.setMaxWaitMillis(maxWait);
	//// config.setMaxTotal(1024);
	// config.setTestOnBorrow(true);
	// config.setTestOnReturn(true);
	// //Idle时进行连接扫描
	// config.setTestWhileIdle(true);
	// //表示idle object evitor两次扫描之间要sleep的毫秒数
	// config.setTimeBetweenEvictionRunsMillis(30000);
	// //表示idle object evitor每次扫描的最多的对象数
	// config.setNumTestsPerEvictionRun(10);
	// //表示一个对象至少停留在idle状态的最短时间，然后才能被idle object
	// evitor扫描并驱逐；这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
	// config.setMinEvictableIdleTimeMillis(60000);
	// return config;
	// }

	// @Bean
	// public JedisConnectionFactory redisConnectionFactorys() {
	// JedisConnectionFactory factory = new JedisConnectionFactory();
	// factory.setHostName(url);
	// factory.setPort(port);
	// factory.setPassword(password);
	// factory.setTimeout(timeout); // 设置连接超时时间
	// return factory;
	// }

	// @Bean
	// public JedisPool redisPoolFactory() {
	// JedisPool jedisPool = new JedisPool(getRedisConfig(), url,
	// port,timeout,password);
	// return jedisPool;
	// }

	class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
		private Class<T> clazz;

		public FastJsonRedisSerializer(Class<T> clazz) {
			super();
			this.clazz = clazz;
		}

		@Override
		public byte[] serialize(T t) throws SerializationException {
			if (t == null) {
				return new byte[0];
			}
			return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(Charset.forName("UTF-8"));
		}

		@Override
		public T deserialize(byte[] bytes) throws SerializationException {
			if (bytes == null || bytes.length <= 0) {
				return null;
			}
			String str = new String(bytes, Charset.forName("UTF-8"));
			return (T) JSON.parseObject(str, clazz);
		}
	}

}
